home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 7 / Gekikoh Dennoh Club Vol. 7 (Japan).7z / Gekikoh Dennoh Club Vol. 7 (Japan) (Track 01).bin / games / otoko / source.lzh / FuncEnemy / mvlaser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-14  |  6.7 KB  |  301 lines

  1. #include <xsp2lib.h>
  2.  
  3. #include "../otoko.h"
  4. #include "../player.h"
  5. #include "../enemy.h"
  6. #include "../eshot.h"
  7. #include "../effect.h"
  8. #include "../priority.h"
  9. #include "../sound.h"
  10. #include "../entry.h"
  11.  
  12. #ifdef DEBUG
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include "../txfont.h"
  16. #endif
  17.  
  18. #define PALET_MVLASER    0x0400
  19. #define SPEED_LASER        28
  20.  
  21. #define HP_0        600
  22. #define TIMER_1        1500    /* これ以上経ったら撤退 */
  23.  
  24. #define SPEED_1        3    /* 加速度 */
  25. #define SPEED_1N    28    /* 加速度を足す回数 */
  26.  
  27. #define abs(x)  ((x) >= 0 ? (int) (x) : (int) -(x))
  28. #define SEQ_2ND        2
  29.  
  30. #define ENTRY_CONTROL_ADD    100    /* entry_control に足す値 */
  31.  
  32. enum {
  33.     MOVETO_INIT = 0,    /* 初期状態 */
  34.     MOVETO_L2R,        /* 左から右に移動 */
  35.     MOVETO_R2L
  36. };
  37.  
  38. static short EnemyMoveMvLaser (ENEMY *);
  39. static void EnemyTiniMvLaser (ENEMY *);
  40.  
  41.  
  42. void EnemyInitMvLaser (ENEMY * p)
  43. {
  44.     if (p->lx < 0)
  45.         p->vx = 4 * 65536;
  46.     else
  47.         p->vx = -4 * 65536;
  48.     p->vy = -(2.5 * 65536);
  49.     p->hit_px = 24;
  50.     p->hit_py = 16;
  51.     p->hit_sx = 24;
  52.     p->hit_sy = 16;
  53.     p->hit_cx = 6;
  54.     p->damage = p->damage_core = 0;
  55.     p->timer = 0;
  56.     p->flash = 0;
  57.     p->hp = HP_0;
  58.     p->pt = obj_mvlaser;
  59.     p->core_pt = sp_core01;
  60.     p->core_info = PALET_CORE_BLUE | PRIORITY_BOSS;
  61.     p->seq = 0;
  62.     p->func_enemy_move = EnemyMoveMvLaser;
  63.     p->func_enemy_tini = EnemyTiniMvLaser;
  64.  
  65.     p->s_work = 0;
  66.     p->s_work2 = 0;
  67.  
  68.     /* まず砲台を生成 */
  69.     p->parts1 = EnemyInit (ENEMY_MVLASERH, -32, 0, 0, p);
  70.     p->parts2 = EnemyInit (ENEMY_MVLASERH, 32, 0, 0, p);
  71.  
  72.     entry_control += ENTRY_CONTROL_ADD;
  73. }
  74.  
  75.  
  76.  
  77. static short EnemyMoveMvLaser (ENEMY * p)
  78. {
  79.     /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  80.     p->x = (p->lx += p->vx) >> 16;
  81.     p->y = (p->ly += p->vy) >> 16;
  82.     p->timer++;
  83.  
  84. #ifdef DEBUG
  85.     {
  86.         char temp_str[64];
  87.         sprintf (temp_str, "TIMER %05hd", p->timer);
  88.         TxfontCursor (20, 3);
  89.         TxfontPuts (temp_str);
  90.         sprintf (temp_str, "   HP %05hd", p->hp);
  91.         TxfontCursor (20, 4);
  92.         TxfontPuts (temp_str);
  93.     }
  94. #endif
  95.  
  96.     switch (p->seq) {
  97.     case 0:        /* 減速 */
  98.         if (p->vx > 0)
  99.             p->vx -= 2400;
  100.         else
  101.             p->vx += 2400;
  102.         if (abs (p->vx) < 2400)
  103.             p->vx = 0;
  104.  
  105.         if (p->vy < 0) {
  106.             p->vy += 2048;
  107.         } else {
  108.             p->seq++;
  109.             p->vx = 0;
  110.             p->vy = 0;
  111.             p->m_work = MOVETO_INIT;    /* 移動方向 */
  112.         }
  113.         break;
  114.  
  115.         /* 第1形態 */
  116.     case 1:        /* 左右に移動しつつ攻撃 */
  117.         /* まず移動処理 */
  118.         if (p->m_work == MOVETO_INIT) {
  119.             /* 初期状態なら */
  120.             if (p->x > 128 + 16)
  121.                 p->m_work = MOVETO_R2L;    /* 移動方向 */
  122.             else
  123.                 p->m_work = MOVETO_L2R;    /* 移動方向 */
  124.             p->m_work2 = 0;
  125.         }
  126.         switch (p->m_work2) {
  127.         case 0:
  128.             p->vx = p->vy = 0;    /* 念のため */
  129.             /* 左の砲台が健在なら */
  130.             if ((p->parts1) && (p->parts1->seq == 0))
  131.                 p->parts1->seq = 1;    /* 発射指示 */
  132.             /* 右の砲台が健在なら */
  133.             if ((p->parts2) && (p->parts2->seq == 0))
  134.                 p->parts2->seq = 1;    /* 発射指示 */
  135.             /* 砲台が両方ともなくなったら */
  136.             if ((p->parts1 == 0) && (p->parts2 == 0)) {
  137.                 p->seq++;
  138.                 p->s_work = p->s_work2 = 0;
  139.                 p->core_info = PALET_CORE_RED | PRIORITY_BOSS;
  140.             }
  141.             p->m_work2++;
  142.             p->m_work3 = 0;
  143.             break;
  144.         case 1:
  145.             if (p->m_work3++ > 20) {
  146.                 /* 初回なら */
  147.                 signed short dx, dy;
  148.                 signed short dx_table[3] =
  149.                 {0, 54 + 16, 256 - 54 + 16};
  150.                 short m_work_table[3] =
  151.                 {MOVETO_INIT, MOVETO_R2L, MOVETO_L2R};
  152.  
  153.                 p->m_work2++;
  154.                 /* 順に左→中央→右→中央→左へ移動 */
  155.                 dx = dx_table[p->m_work];
  156.                 p->m_work = m_work_table[p->m_work];
  157.  
  158.                 /* player->y は乱数の種として使用しています */
  159.                 if (SHORT_LY < 80)
  160.                     dy = (((unsigned short) rndtable[(player->y) & 0xff]) / 4 + 32 + 16);
  161.                 else
  162.                     dy = 64;
  163.                 /* 移動方向を設定 */
  164.                 SubEnemyMoveToInit (p, dx, dy, SPEED_1, SPEED_1N);
  165.                 p->s_work = 0;
  166.                 p->s_work2 = 0;
  167.             }
  168.             break;
  169.         case 2:
  170.             /* 設定値に従って移動 */
  171.             if (SubEnemyMoveTo (p) < 0)
  172.                 p->m_work2 = 0;    /* 移動方向再設定 */
  173.             break;
  174.         }
  175.  
  176.         /* 次に攻撃処理 */
  177.         if (p->m_work2 == 2) {
  178.             switch (p->s_work++) {
  179.             case 0:
  180.                 if (p->s_work2 == 0)
  181.                     p->s_angle = 64 + 8 * 3;
  182.                 else
  183.                     p->s_angle = 64 - 8 * 3;
  184.                 p->s_work3 = 7;    /* 弾の速度 */
  185.                 break;
  186. #define    INTERVAL1_2    7
  187.             case 10 + INTERVAL1_2 * 0:
  188.                 SoundSetSE (SE_ESHOT_M);    /* 敵ショット音 */
  189.             case 10 + INTERVAL1_2 * 1:
  190.             case 10 + INTERVAL1_2 * 2:
  191.             case 10 + INTERVAL1_2 * 3:
  192.             case 10 + INTERVAL1_2 * 4:
  193.             case 10 + INTERVAL1_2 * 5:
  194.             case 10 + INTERVAL1_2 * 6:
  195.             case 10 + INTERVAL1_2 * 7:
  196.                 EshotInit (ESHOT_NRG02, SHORT_LX, SHORT_LY, p->s_work3, p->s_angle, 4);
  197.                 if (p->s_work2 == 0)
  198.                     p->s_angle -= 8;
  199.                 else
  200.                     p->s_angle += 8;
  201.                 p->s_work3++;
  202.                 break;
  203.             case 60:
  204.                 p->s_work = 0;
  205.                 if (p->s_work2 == 0)
  206.                     p->s_work2 = 1;
  207.                 else
  208.                     p->s_work2 = 0;
  209.                 break;
  210.             default:
  211.                 break;
  212.             }
  213.         }
  214.         break;
  215.  
  216.         /* 第2形態(砲台が破壊された後) */
  217.     case SEQ_2ND:
  218.         if (p->vx > 4096)
  219.             p->vx -= 4096;
  220.         else if (p->vx < -4096)
  221.             p->vx += 4096;
  222.         if (SHORT_VY < 1)
  223.             p->vy += 2048;
  224.         if (p->s_work2++ > 2) {
  225.             p->s_work2 = 0;
  226.             EshotInit (ESHOT_NRG04, SHORT_LX, SHORT_LY, 9, (rndtable[p->s_angle++] & 127), 4);
  227.             EshotInit (ESHOT_NRG04, SHORT_LX, SHORT_LY, 9, (rndtable[p->s_angle++] & 127), 4);
  228.             SoundSetSE (SE_ESHOT_M);    /* 敵ショット音 */
  229.         }
  230.         /* 画面外に出たら消去 */
  231.         if (SHORT_LY > 256 + 48 + 16)
  232.             return (-1);    /* 消去 */
  233.         break;
  234.     }
  235.     if ((p->seq < SEQ_2ND) && (p->timer > TIMER_1))
  236.         p->seq = SEQ_2ND;
  237.  
  238.     if ((p->parts1) && (p->parts1->child_death))
  239.         p->parts1 = 0;    /* これ以降参照しない */
  240.     if ((p->parts2) && (p->parts2->child_death))
  241.         p->parts2 = 0;    /* これ以降参照しない */
  242.  
  243.  
  244.  
  245.  
  246.     /* 自機ショットに当たった時の処理 */
  247.     if (p->damage) {
  248.         if (p->damage_core) {
  249.             SoundSetSE (SE_CORE_DAMAGE);
  250.             p->info = PALET_RED | PRIORITY_BOSS;
  251.             p->damage_core = 0;
  252.         } else {
  253.             SoundSetSE (SE_DAMAGE);
  254.             p->info = PALET_DAMAGE | PRIORITY_BOSS;
  255.         }
  256.         if ((p->hp -= p->damage) <= 0) {
  257.             EffectInit (EFFECT_EXPL, 0, p->x, p->y);
  258.             SoundSetSE (SE_EXPL_M);    /* 中ボス爆発音 */
  259.             if (p->core_info == (PALET_CORE_RED | PRIORITY_BOSS))
  260.                 EffectInit (EFFECT_POINTS_RED, POINTS_8000, p->x, p->y);
  261.             else
  262.                 EffectInit (EFFECT_POINTS_BLUE, POINTS_2000, p->x, p->y);
  263.             if (disp_level == DISP_LEVEL_HIGH)
  264.                 EffectInit (EFFECT_HAHENMINI, 0, p->x, p->y);
  265.             if (!eshot_erase)
  266.                 eshot_erase = ESHOT_ERASE;    /* 弾消し */
  267.             return (-1);    /* 消去 */
  268.         }
  269.         p->damage = 0;
  270.         p->flash = TIMER_FLASH_DAMAGE;
  271.     } else {
  272.         if ((p->flash++ > TIMER_FLASH_RED) && (p->hp < 200)) {
  273.             p->info = PALET_RED | PRIORITY_BOSS;
  274.             if (p->flash > TIMER_FLASH_NORMAL)
  275.                 p->flash = 0;
  276.         } else {
  277.             p->info = PALET_MVLASER | PRIORITY_BOSS;
  278.         }
  279.     }
  280.     xobj_set_st (p);
  281.  
  282.     /* コアの表示 */
  283.     p->core_x = p->x - 8;    /* コアの中心は (-8,-8) ドットずれる */
  284.     p->core_y = p->y - 8;
  285.     xsp_set_st (&(p->core_x));
  286.  
  287.     return (0);
  288. }
  289.  
  290.  
  291.  
  292. static void EnemyTiniMvLaser (ENEMY * p)
  293. {
  294.     /* パーツが存在していたら消すように指示 */
  295.     if (p->parts1)
  296.         p->parts1->child_kill = !0;
  297.     if (p->parts2)
  298.         p->parts2->child_kill = !0;
  299.     entry_control -= ENTRY_CONTROL_ADD;
  300. }
  301.